
#include "../io/print.h"
#include "../commons/waiter.h"
#include "../commons/mapa.h"
#include "../commons/errors.h"
#include "../marshaling/querys_answer.h"
#include "../io/drawer.h"
#include "../io/drawer_monitor.h"
#include <signal.h>
#include "../ipcs/semaphores.h"

int hijos;
sem_t * waiter;
int * pids;

pthread_t the_drawer;


void salir(int error){
	if(error != 0)
		switch(error){
			case 1: printf("Error - Insuficiente memoria. \n");break;
			case 2: printf("Error al cargar uno de los archivos. \n");break;
			default: printf("Error inesperado. \n");break;
		}
	exit(EXIT_FAILURE);
	
}

void close_main(int signal){
	int j=0;
	pthread_mutex_lock(&monitor.mutex);
	while(monitor.counter >= monitor.limit){
		pthread_cond_wait(&monitor.cond2, &monitor.mutex);
	}	
	int i;
	for(i=0;i<hijos;i++){
		kill(pids[i], SIGPIPE);
		waitpid(pids[i], NULL, 0);
	}
	free(pids);
	ipc_close();
	close_semaphores();
	pthread_mutex_unlock(&monitor.mutex);

	close_drawer();
	pthread_join(the_drawer, NULL);

	exit(0);
}


int main(int argc, char *argv[]){
  
	if(argc<3){
		exit(EXIT_FAILURE);
	}

	mapa_t mapa = (mapa_t) malloc(sizeof(struct st_mapa_t));
	
	int ret = loadMapa(mapa, argv[1]);
	if(ret != NO_ERRORS){
		free(mapa);
		salir(ret);	
	}
	
	set_map(mapa);
	
	sem_unlink(STARTER);
	add_semephore(STARTER, sem_open(STARTER, O_CREAT | 0666 , 0777, 0));

	sem_unlink(WAITER);
	waiter= sem_open(WAITER, O_CREAT | 0666 , 0777, 0);
	add_semephore(WAITER, waiter);

	marshaling_init();

	hijos=argc-2;

	init_monitor(hijos);
	
	pthread_create(&the_drawer, NULL, drawer, mapa);

	pids=malloc(hijos*sizeof(int));

	int i;
	for(i=0;i<hijos;i++){
		pids[i]=ipc_open("./client", argv+i+2);
	}	
	signal(SIGABRT,close_main);
	signal(SIGPIPE,close_main);
	signal(SIGQUIT,close_main);
	signal(SIGTERM,close_main);
	
	while(!null_drugs_demand()){
		listen_query();
	}
	close_main(0);
}




//set-get min
int min=INT_MAX;
int count;


int get_min() {
	count--;
	int tmp=min;
	if(count==0){
		min=INT_MAX;
	}
	return tmp;
}

int set_if_min(int n){
	
	int i;
	count++;

	if(count==hijos){
		for(i=0;i<hijos;i++){
			sem_post(waiter);
		}
	}

	min=n<min?n:min;
	return min;
}


